#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

// 统计时分多路复用
int statistical_tdm_multiplex(unsigned char *c, const int c_size, 
                             const unsigned char *a, const int a_len, 
                             const unsigned char *b, const int b_len) {
    if (c_size < a_len + b_len) return -1;
    
    int c_index = 0;
    
    for (int i = 0; i < a_len; i++) {
        if (a[i] != 0) c[c_index++] = a[i];
    }
    
    for (int i = 0; i < b_len; i++) {
        if (b[i] != 0) c[c_index++] = b[i];
    }
    
    for (int i = 0; i < a_len; i++) {
        if (a[i] == 0) c[c_index++] = a[i];
    }
    
    for (int i = 0; i < b_len; i++) {
        if (b[i] == 0) c[c_index++] = b[i];
    }
    
    return c_index;
}

int statistical_tdm_demultiplex(unsigned char *a, const int a_size, 
                               unsigned char *b, const int b_size, 
                               const unsigned char *c, const int c_len) {
    if (a_size < 0 || b_size < 0) return -1;
    
    int a_nonzero = 0, b_nonzero = 0;
    int a_zero = 0, b_zero = 0;
    
    for (int i = 0; i < a_size; i++) {
        if (a[i] != 0) a_nonzero++;
        else a_zero++;
    }
    
    for (int i = 0; i < b_size; i++) {
        if (b[i] != 0) b_nonzero++;
        else b_zero++;
    }
    
    if (c_len < a_nonzero + b_nonzero + a_zero + b_zero) return -1;
    
    int c_index = 0;
    
    for (int i = 0; i < a_nonzero; i++) a[i] = c[c_index++];
    for (int i = 0; i < b_nonzero; i++) b[i] = c[c_index++];
    for (int i = a_nonzero; i < a_size; i++) a[i] = c[c_index++];
    for (int i = b_nonzero; i < b_size; i++) b[i] = c[c_index++];
    
    return 0;
}

// 同步时分多路复用
int sync_tdm_multiplex(unsigned char *c, const int c_size, 
                      const unsigned char *a, const int a_len, 
                      const unsigned char *b, const int b_len) {
    int max_len = max(a_len, b_len);
    if (c_size < 2 * max_len) return -1;
    
    int c_index = 0;
    
    for (int i = 0; i < max_len; i++) {
        c[c_index++] = (i < a_len) ? a[i] : 0;
        c[c_index++] = (i < b_len) ? b[i] : 0;
    }
    
    return c_index;
}

int sync_tdm_demultiplex(unsigned char *a, const int a_size, 
                        unsigned char *b, const int b_size, 
                        const unsigned char *c, const int c_len) {
    if (a_size < 0 || b_size < 0) return -1;
    
    int max_size = max(a_size, b_size);
    if (c_len < 2 * max_size) return -1;
    
    for (int i = 0; i < max_size; i++) {
        if (i < a_size) a[i] = c[2 * i];
        if (i < b_size) b[i] = c[2 * i + 1];
    }
    
    return 0;
}

// 频分多路复用 - a序列放在高位，b序列放在低位
int fdm_multiplex(unsigned char *c, const int c_size, 
                 const unsigned char *a, const int a_len, 
                 const unsigned char *b, const int b_len) {
    int max_len = max(a_len, b_len);
    if (c_size < max_len) return -1;
    
    for (int i = 0; i < max_len; i++) {
        unsigned char a_val = (i < a_len) ? (a[i] ? 0x10 : 0) : 0;
        unsigned char b_val = (i < b_len) ? (b[i] ? 0x01 : 0) : 0;
        c[i] = a_val | b_val;
    }
    
    return max_len;
}

int fdm_demultiplex(unsigned char *a, const int a_size, 
                   unsigned char *b, const int b_size, 
                   const unsigned char *c, const int c_len) {
    int max_size = max(a_size, b_size);
    if (c_len < max_size) return -1;
    
    for (int i = 0; i < max_size; i++) {
        if (i < a_size) a[i] = (c[i] & 0x10) ? 1 : 0;
        if (i < b_size) b[i] = (c[i] & 0x01) ? 1 : 0;
    }
    
    return 0;
}

// 码分多路复用 - a使用[1,-1]，b使用[1,1]
int cdm_multiplex(unsigned char *c, const int c_size, 
                 const unsigned char *a, const int a_len, 
                 const unsigned char *b, const int b_len) {
    int max_len = max(a_len, b_len);
    if (c_size < 2 * max_len) return -1;
    
    for (int i = 0; i < max_len; i++) {
        int a_bit = (i < a_len) ? (a[i] ? 1 : 0) : 0;
        int b_bit = (i < b_len) ? (b[i] ? 1 : 0) : 0;
        
        int signal1 = a_bit * 1 + b_bit * 1;
        int signal2 = a_bit * (-1) + b_bit * 1;
        
        c[2*i] = signal1 + 2;
        c[2*i+1] = signal2 + 2;
    }
    
    return 2 * max_len;
}

int cdm_demultiplex(unsigned char *a, const int a_size, 
                   unsigned char *b, const int b_size, 
                   const unsigned char *c, const int c_len) {
    int max_size = max(a_size, b_size);
    if (c_len < 2 * max_size) return -1;
    
    for (int i = 0; i < max_size; i++) {
        if (i < a_size) {
            int signal1 = c[2*i] - 2;
            int signal2 = c[2*i+1] - 2;
            int a_bit = (signal1 * 1 + signal2 * (-1)) / 2;
            a[i] = a_bit ? 1 : 0;
        }
        
        if (i < b_size) {
            int signal1 = c[2*i] - 2;
            int signal2 = c[2*i+1] - 2;
            int b_bit = (signal1 * 1 + signal2 * 1) / 2;
            b[i] = b_bit ? 1 : 0;
        }
    }
    
    return 0;
}

// 统一接口
int multiplex(unsigned char *c, const int c_size, 
             const unsigned char *a, const int a_len, 
             const unsigned char *b, const int b_len) {
    return sync_tdm_multiplex(c, c_size, a, a_len, b, b_len);
}

int demultiplex(unsigned char *a, const int a_size, 
               unsigned char *b, const int b_size, 
               const unsigned char *c, const int c_len) {
    return sync_tdm_demultiplex(a, a_size, b, b_size, c, c_len);
}

// 测试函数
void test_multiplexing(const char* method_name,
                      int (*mux_func)(unsigned char*, const int, const unsigned char*, const int, const unsigned char*, const int),
                      int (*demux_func)(unsigned char*, const int, unsigned char*, const int, const unsigned char*, const int)) {
    unsigned char a[] = {1, 0, 1, 1, 0};
    unsigned char b[] = {0, 1, 1, 0, 1, 0, 1};
    const int a_len = sizeof(a) / sizeof(a[0]);
    const int b_len = sizeof(b) / sizeof(b[0]);
    
    unsigned char c[100] = {0};
    int c_len = mux_func(c, 100, a, a_len, b, b_len);
    
    if (c_len < 0) {
        cout << method_name << " 多路复用失败！" << endl;
        return;
    }
    
    cout << method_name << " 多路复用后的信号：";
    for (int i = 0; i < c_len; i++) cout << (int)c[i] << " ";
    cout << endl;
    
    unsigned char a_recovered[10] = {0};
    unsigned char b_recovered[10] = {0};
    
    int result = demux_func(a_recovered, a_len, b_recovered, b_len, c, c_len);
    
    if (result < 0) {
        cout << method_name << " 解复用失败！" << endl;
        return;
    }
    
    cout << method_name << " 解复用后的a序列：";
    for (int i = 0; i < a_len; i++) cout << (int)a_recovered[i] << " ";
    cout << endl;
    
    cout << method_name << " 解复用后的b序列：";
    for (int i = 0; i < b_len; i++) cout << (int)b_recovered[i] << " ";
    cout << endl;
    
    bool a_correct = true, b_correct = true;
    for (int i = 0; i < a_len; i++) {
        if ((a[i] != 0) != (a_recovered[i] != 0)) {
            a_correct = false;
            break;
        }
    }
    
    for (int i = 0; i < b_len; i++) {
        if ((b[i] != 0) != (b_recovered[i] != 0)) {
            b_correct = false;
            break;
        }
    }
    
    if (a_correct && b_correct) cout << method_name << " 解复用正确！" << endl;
    else cout << method_name << " 解复用错误！" << endl;
    
    cout << "----------------------------" << endl;
}

int main() {
    cout << "测试各种多路复用方法：" << endl;
    cout << "----------------------------" << endl;
    
    test_multiplexing("统计时分多路复用", statistical_tdm_multiplex, statistical_tdm_demultiplex);
    test_multiplexing("同步时分多路复用", sync_tdm_multiplex, sync_tdm_demultiplex);
    test_multiplexing("频分多路复用", fdm_multiplex, fdm_demultiplex);
    test_multiplexing("码分多路复用", cdm_multiplex, cdm_demultiplex);
    
    return 0;
}